
package com.idealighter.game.roomcard.games.mustniuniu.manager;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.idealighter.game.core.assertions.HuohuaAssert;
import com.idealighter.game.core.common.Game;
import com.idealighter.game.games.common.SeatState;
import com.idealighter.game.games.common.niuniu.NiuNiuCard;
import com.idealighter.game.games.sirenniuniu.manager.SiRenNiuNiuMgr;
import com.idealighter.game.player.manager.PlayerMgr;
import com.idealighter.game.player.struct.Player;
import com.idealighter.game.roomcard.games.mustniuniu.MustNiuNiuCardsTypeComparator;
import com.idealighter.game.roomcard.games.mustniuniu.MustNiuNiuCardsTypeGetter;
import com.idealighter.game.roomcard.games.mustniuniu.bo.BetTypeBo;
import com.idealighter.game.roomcard.games.mustniuniu.constant.MustNiuNiuCardType;
import com.idealighter.game.roomcard.games.mustniuniu.manager.control.ControlCard;
import com.idealighter.game.roomcard.games.mustniuniu.struct.MustNiuNiuSeat;
import com.idealighter.game.roomcard.games.mustniuniu.struct.MustNiuNiuTable;
import com.idealighter.game.roomcard.struct.gamgcfg.value.NiuNiuRoomCardGameCfgValue.MustNiuNiuExtrBetOptionPo;
import com.idealighter.utils.check.EmptyUtil;
import com.idealighter.utils.code.RandCodeUtil;
import com.idealighter.utils.json.JsonUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 四人牛牛控制 .
 * 
 * @date 2016年1月20日 下午4:46:55
 *
 */
@Singleton
public class MustNiuNiuControlScript {

  private static final Logger LOG = LoggerFactory.getLogger(MustNiuNiuControlScript.class);

  private static final Game THIS_GAME = Game.MUST_NIUNIU;

  @Inject
  private MustNiuNiuMsgMgr msgMgr;
  @Inject
  private PlayerMgr playerMgr;


  /**
   * @Title dealSccbFirstFourCards.
   * @Description 明牌抢庄-发四张牌
   * @date 2018年6月2日 下午2:15:23
   * @param table .
   */
  public void dealSccbFirstFourCards(MustNiuNiuTable table) {
    table.getNiuNiuCardTypePlayers().clear();
    List<NiuNiuCard> tableCards = table.getCards();
    int cardIndex = 0;
    // 洗牌
    Collections.shuffle(table.getCards());
    // 发四张牌
    for (MustNiuNiuSeat seat : table.getGameSeats(true)) {
      // 只给已经准备的玩家发牌
      if (seat.getState().equals(SeatState.GAMING)) {
        List<NiuNiuCard> cards =
            tableCards.subList(cardIndex, cardIndex += (MustNiuNiuMgr.PLAYER_CARDS - 1));
        seat.getCards().clear();
        seat.getCards().addAll(cards);
        LOG.info("[{}]发送玩家[{}][{}]四张牌[{}]", THIS_GAME.getDesc(), seat.getPlayerId(),
            seat.getPlayerName(), seat.getCards());
      }
    }
    msgMgr.sendDealSccbFirstFourCardsMsg(table);
  }

  /**
   * @Title controlDealCards.
   * @Description 控制发牌(明牌抢庄发一张牌，其他发5张)
   * @date 2018年6月5日 上午9:34:04
   * @param table .
   */
  public void controlDealCards(MustNiuNiuTable table) {
    table.getNiuNiuCardTypePlayers().clear();
    // 洗牌
    Collections.shuffle(table.getCards());
    // 如果是明牌抢庄
    if (table.isShowCardCallBanker()) {
      LOG.info("控牌前===========>>>>>>>>>>>>>>>>>>");
      for (MustNiuNiuSeat seat : table.getGameSeats(true)) {
        List<NiuNiuCard> cards = seat.getCards();
        HuohuaAssert.isTrue(cards.size() == 4);
        LOG.info("控牌前玩家[{}]牌[{}]", seat.getPlayerId(), JsonUtil.toJson(cards));
      }
      LOG.info("控牌前<<<<<<<<<<<<<<<<<<===========");
      controlLastCard(table);
    } else { // 其他情况发五张
      controlFiveCards(table);
    }
  }

  private void normalDealOneCard(MustNiuNiuTable table) {
    List<NiuNiuCard> tableCards = table.getCards();
    MustNiuNiuSeat dealer = table.dealer();

    List<NiuNiuCard> alreadySend = new ArrayList<NiuNiuCard>();
    for (MustNiuNiuSeat s : table.getGameSeats(true)) {
      if (s.getState().equals(SeatState.GAMING)) {
        alreadySend.addAll(s.getCards());
      }
    }

    // 发完所有的牌
    for (MustNiuNiuSeat s : table.getGameSeats(true)) {
      if (s.getState().equals(SeatState.GAMING)) {
        for (NiuNiuCard card : tableCards) {
          if (!alreadySend.contains(card)) {
            s.getCards().add(card);
            alreadySend.add(card);
            break;
          }
        }
      }
    }

    List<MustNiuNiuCardType> cardTypeList = new ArrayList<>(table.getCardTypeMap().keySet());
    // 先发庄家的牌
    dealDealerCards(dealer, dealer.getCards(), cardTypeList);
    // 再发庄家的牌
    for (MustNiuNiuSeat s : table.getGameSeats(true)) {
      if (s.getState().equals(SeatState.GAMING) && !s.isDealer()) {
        dealPlayerCards(s, s.getCards(), cardTypeList);
      }
    }
  }

  private void controlFiveCards(MustNiuNiuTable table) {
    // 所有人
    MustNiuNiuSeat dealer = null;

    List<MustNiuNiuSeat> cardSeats = new ArrayList<>();

    for (MustNiuNiuSeat seat : table.getGameSeats(true)) {
      if (seat.isDealer()) {
        dealer = seat;
      } else if (seat.getState().equals(SeatState.GAMING)) {
        cardSeats.add(seat);
      }
    }

    /*
     * 提前生成N副排好序的牌.
     */
    LinkedList<List<NiuNiuCard>> sortedCardsList = new LinkedList<>();
    int cardIndex = 0;
    int handCards = cardSeats.size() + 1;
    for (int i = 0; i < handCards; i++) {
      sortedCardsList
          .add(table.getCards().subList(cardIndex, cardIndex += SiRenNiuNiuMgr.PLAYER_CARDS));
    }

    List<MustNiuNiuCardType> optionCardTypes = new ArrayList<>(table.getCardTypeMap().keySet());
    // 玩家的牌进行排序
    sortedCardsList.sort((cards1, cards2) -> {
      MustNiuNiuCardType cards1Type =
          MustNiuNiuCardsTypeGetter.getCardsType(cards1, optionCardTypes);
      MustNiuNiuCardType cards2Type =
          MustNiuNiuCardsTypeGetter.getCardsType(cards2, optionCardTypes);

      if (MustNiuNiuCardsTypeComparator.compare(cards1, cards1Type, cards2, cards2Type)) {
        return -1;
      } else {
        return 1;
      }
    });

    // 根据胜率 找出与庄家的胜率
    Player dealerPlayer = playerMgr.getPlayer(dealer.getPlayerId());
    int dealerWinRate = dealerPlayer.getWinRate();

    int winCount = 0;

    Map<Long, Boolean> maps = new HashMap<>();

    for (MustNiuNiuSeat seat : cardSeats) {
      long playerId = seat.getPlayerId();
      Player seatPlayer = playerMgr.getPlayer(playerId);
      int playerWinRate = seatPlayer.getWinRate();

      boolean playerWin = RandCodeUtil.random(dealerWinRate + playerWinRate) <= playerWinRate;

      if (playerWin) {
        winCount++;
      }

      maps.put(playerId, playerWin);
    }

    // 取出对应的牌
    List<NiuNiuCard> dealerCards = sortedCardsList.remove(winCount);
    handCards--;

    dealDealerCards(dealer, dealerCards, optionCardTypes);

    for (MustNiuNiuSeat seat : cardSeats) {
      if (maps.get(seat.getPlayerId())) {
        int index = RandCodeUtil.random(0, winCount - 1);
        List<NiuNiuCard> playCards = sortedCardsList.remove(index);
        dealPlayerCards(seat, playCards, optionCardTypes);
        handCards--;
        winCount--;
      } else {
        int index = RandCodeUtil.random(winCount, handCards - 1);
        List<NiuNiuCard> playCards = sortedCardsList.remove(index);
        dealPlayerCards(seat, playCards, optionCardTypes);
        handCards--;
      }
    }
  }

  private void controlLastCard(MustNiuNiuTable table) {
    // 剩余的牌
    List<NiuNiuCard> leftCards = new ArrayList<>(table.getCards());
    for (MustNiuNiuSeat s : table.getGameSeats(true)) {
      if (s.getState().equals(SeatState.GAMING)) {
        leftCards.removeAll(s.getCards());
      }
    }
    // 乱序
    Collections.shuffle(leftCards);

    // 所有参与的人
    MustNiuNiuSeat dealer = null;

    List<MustNiuNiuSeat> cardSeats = new ArrayList<>();

    for (MustNiuNiuSeat seat : table.getGameSeats(true)) {
      if (!seat.isByStander() && seat.isDealer()) {
        dealer = seat;
      } else if (seat.getState().equals(SeatState.GAMING)) {
        cardSeats.add(seat);
      }
    }

    // 根据胜率 找出与庄家的胜率
    Player dealerPlayer = playerMgr.getPlayer(dealer.getPlayerId());
    int dealerWinRate = dealerPlayer.getWinRate();

    Map<Long, Boolean> winMap = new HashMap<>();
    // Map<Long, List<ControlCard>> cardSetMap = new HashMap<>();

    for (MustNiuNiuSeat seat : cardSeats) {
      long playerId = seat.getPlayerId();
      Player seatPlayer = playerMgr.getPlayer(playerId);
      int playerWinRate = seatPlayer.getWinRate();

      boolean playerWin = RandCodeUtil.random(dealerWinRate + playerWinRate) <= playerWinRate;

      winMap.put(playerId, playerWin);
      // cardSetMap.put(playerId, new ArrayList<ControlCard>());
    }

    List<MustNiuNiuCardType> optionCardTypes = new ArrayList<>(table.getCardTypeMap().keySet());

    // 计算所有牌组情况
    List<ControlCard> controlCards = new ArrayList<>(cardSeats.size() * leftCards.size());

    // 庄家 牌组
    for (NiuNiuCard lastCard : leftCards) {
      ControlCard controlCard = new ControlCard();
      List<NiuNiuCard> tmpCards = new ArrayList<>(dealer.getCards());
      tmpCards.add(lastCard);

      MustNiuNiuCardType cardType =
          MustNiuNiuCardsTypeGetter.getCardsType(tmpCards, optionCardTypes);
      controlCard.setCardType(cardType);
      controlCard.setCards(tmpCards);
      controlCard.setLastCard(lastCard);
      controlCard.setPlayerId(dealer.getPlayerId());
      controlCards.add(controlCard);
    }

    for (MustNiuNiuSeat seat : cardSeats) {
      for (NiuNiuCard lastCard : leftCards) {
        ControlCard controlCard = new ControlCard();
        List<NiuNiuCard> tmpCards = new ArrayList<>(seat.getCards());
        tmpCards.add(lastCard);

        MustNiuNiuCardType cardType =
            MustNiuNiuCardsTypeGetter.getCardsType(tmpCards, optionCardTypes);
        controlCard.setCardType(cardType);
        controlCard.setCards(tmpCards);
        controlCard.setLastCard(lastCard);
        controlCard.setPlayerId(seat.getPlayerId());
        controlCards.add(controlCard);
      }
    }

    // 牌组排序
    controlCards.sort((cards1, cards2) -> {
      if (MustNiuNiuCardsTypeComparator.compareByAllCard(cards1.getCards(), cards1.getCardType(),
          cards2.getCards(), cards2.getCardType())) {
        return -1;
      } else {
        return 1;
      }
    });

    // 找到庄家所有的牌组下标
    List<Integer> dealerIndexs = new ArrayList<>(22);

    for (int i = 0; i < controlCards.size(); i++) {
      if (controlCards.get(i).getPlayerId() == dealer.getPlayerId()) {
        dealerIndexs.add(i);
      }
    }


    int randomIndex = RandCodeUtil.random(dealerIndexs.size());

    boolean isOver = false;

    // 开始查找
    while (!isOver && randomIndex >= 0 && randomIndex < dealerIndexs.size()
        && dealerIndexs.size() > 0) {
      // 随机庄家一副牌
      int currentDealerIndex = dealerIndexs.remove(randomIndex);
      ControlCard dealerControlCard = controlCards.get(currentDealerIndex);

      Multimap<Long, ControlCard> cardSetMultimap = ArrayListMultimap.create();

      for (int i = 0; i < currentDealerIndex; i++) {
        ControlCard controlCard = controlCards.get(i);
        // 剔除庄家牌
        if (controlCard.getPlayerId() == dealer.getPlayerId()) {
          continue;
        }
        // 剔除 输给庄家的牌
        if (!winMap.get(controlCard.getPlayerId())) {
          continue;
        }

        cardSetMultimap.put(controlCard.getPlayerId(), controlCard);
      }

      for (int i = currentDealerIndex + 1; i < controlCards.size(); i++) {
        ControlCard controlCard = controlCards.get(i);

        // 剔除庄家牌
        if (controlCard.getPlayerId() == dealer.getPlayerId()) {
          continue;
        }

        // 剔除 赢了庄家的牌
        if (winMap.get(controlCard.getPlayerId())) {
          continue;
        }

        cardSetMultimap.put(controlCard.getPlayerId(), controlCard);
      }

      // 集合校验
      // 归类需要处理的牌组
      List<List<ControlCard>> duplicates = new ArrayList<>(); // 排重列表.
      List<List<ControlCard>> waitDeals = new ArrayList<>(); // 直接处理列表.

      // 赢的集合与输的集合必须至少有一个元素
      int winNotFit = 0;
      int loseNotFit = 0;
      for (MustNiuNiuSeat seat : cardSeats) {
        Collection<ControlCard> tempCards = cardSetMultimap.get(seat.getPlayerId());
        if (tempCards == null || tempCards.size() == 0) {
          if (winMap.get(seat.getPlayerId())) {
            winNotFit++;
          } else {
            loseNotFit++;
          }
        } else {
          if (tempCards.size() <= cardSeats.size()) {
            duplicates.add(new ArrayList<>(tempCards));
          } else {
            waitDeals.add(new ArrayList<>(tempCards));
          }
        }
      }
      // 赢的和输的都找不到满足的
      // 不可能找到满足的情况
      // 离开，随机
      if (winNotFit > 0 && loseNotFit > 0) {
        break;
      }

      if (winNotFit > 0) { // 赢的集合不合法，右移动
        randomIndex++;
        continue;
      } else if (loseNotFit > 0) { // 输的集合不合法，左移动
        randomIndex--;
        continue;
      }

      // 集合排重
      Map<Long, NiuNiuCard> usedCardMap = new HashMap<>(duplicates.size());

      int[] currentIndexs = new int[duplicates.size()];
      Arrays.fill(currentIndexs, 0);
      // 1.要排重

      if (duplicates.size() > 0) {
        int duplicateIndex = 0;
        while (duplicateIndex < duplicates.size()) {
          List<ControlCard> tempCards = duplicates.get(duplicateIndex);
          long playerId = tempCards.get(0).getPlayerId();
          int currentIndex = currentIndexs[duplicateIndex];
          while (currentIndex < tempCards.size()) {
            ControlCard card = tempCards.get(currentIndex);
            // 跳过 用户用过了与庄家用过了
            if (usedCardMap.containsValue(card.getLastCard())
                || dealerControlCard.getLastCard().equals(card.getLastCard())) {
              currentIndexs[duplicateIndex]++;
            } else {
              usedCardMap.put(card.getPlayerId(), card.getLastCard());
              duplicateIndex++;
              break;
            }
            currentIndex = currentIndexs[duplicateIndex];
          }
          // 查找下一级找不到，需要回滚
          if (currentIndex >= tempCards.size()) {

            // 回退已经使用过的牌型
            usedCardMap.remove(playerId);
            // 回溯上一步
            duplicateIndex--;
            if (duplicateIndex < 0) {
              break;
            }
            // 查找下一个
            currentIndexs[duplicateIndex]++;
            // 重置子集的节点
            for (int i = duplicateIndex + 1; i < currentIndexs.length; i++) {
              currentIndexs[i] = 0;
            }
          }
        }

        // 失败
        if (duplicateIndex < duplicates.size()) {
          if (dealerIndexs.size() == 0) {
            break;
          }
          randomIndex = RandCodeUtil.random(dealerIndexs.size());
          continue;
        }
      }

      // 2.处理不需要排重
      if (waitDeals.size() > 0) {
        for (List<ControlCard> currentControlDeals : waitDeals) {
          for (ControlCard controlCard : currentControlDeals) {
            if (!usedCardMap.containsValue(controlCard.getLastCard())
                && !dealerControlCard.getLastCard().equals(controlCard.getLastCard())) {
              usedCardMap.put(controlCard.getPlayerId(), controlCard.getLastCard());
              break;
            }
          }
        }
      }

      // 处理庄家牌
      dealDealerCards(dealer, dealerControlCard.getCards(), optionCardTypes);

      // 处理闲家牌
      for (MustNiuNiuSeat seat : cardSeats) {
        List<NiuNiuCard> tempCards = seat.getCards();
        tempCards.add(usedCardMap.get(seat.getPlayerId()));
        // LOG.info("玩家牌 {}", tempCards);
        dealPlayerCards(seat, tempCards, optionCardTypes);
      }

      LOG.info("控牌后===========>>>>>>>>>>>>>>>>>>");
      for (MustNiuNiuSeat seat : table.getGameSeats(true)) {
        LOG.info("控牌后玩家[{}]牌[{}]", seat.getPlayerId(), JsonUtil.toJson(seat.getCards()));
      }
      LOG.info("控牌后<<<<<<<<<<<<<<<<<<===========");

      isOver = true;
    }

    if (!isOver) {
      // 找不到牌型随机处理
      normalDealOneCard(table);
    }

  }

  // /**
  // * 正常发牌 .
  // *
  // * @param table .
  // */
  // private void normalDealCards(MustNiuNiuTable table) {
  // List<NiuNiuCard> tableCards = table.getCards();
  // MustNiuNiuSeat dealer = table.dealer();
  // int cardIndex = 0;
  //
  // // 先发庄家的牌,有了庄家的牌才能确定输赢计算筹码
  // List<MustNiuNiuCardType> cardTypeList = new ArrayList<>(table.getCardTypeMap().keySet());
  // dealDealerCards(dealer,
  // tableCards.subList(cardIndex, cardIndex += MustNiuNiuMgr.PLAYER_CARDS), cardTypeList);
  //
  // /*
  // * 再发闲家牌，由于先发的庄家牌，所以发闲家牌时已经能计算输赢筹码了 .
  // */
  // for (MustNiuNiuSeat seat : table.getGameSeats(true)) {
  // if (seat.getState().equals(SeatState.GAMING)
  // && seat.getPlayerId() != dealer.getPlayerId()) {
  // dealPlayerCards(seat,
  // tableCards.subList(cardIndex, cardIndex += MustNiuNiuMgr.PLAYER_CARDS), cardTypeList);
  // }
  // }
  // }

  /**
   * @Title dealDealerCards.
   * @Description 给庄家发牌
   * @date 2018年6月5日 上午10:15:25
   * @param dealer 庄家座位
   * @param cards 庄家的牌
   * @param cardTypes 支持的牌型
   */
  private void dealDealerCards(MustNiuNiuSeat dealer, List<NiuNiuCard> cards,
      List<MustNiuNiuCardType> cardTypes) {
    MustNiuNiuCardType cardsType =
        MustNiuNiuCardsTypeGetter.getCardsType(cards, dealer.getBestCards(), cardTypes);
    if (!dealer.getCards().equals(cards)) {
      dealer.getCards().clear();
      dealer.getCards().addAll(cards);
    }
    dealer.setCardsType(cardsType);

    MustNiuNiuTable table = dealer.table();
    if (table.isNiuNiuBeBanker() && cardsType.niu >= MustNiuNiuCardType.NIU_NIU.niu) {
      List<Long> niuniuCardPlayers = table.getNiuNiuCardTypePlayers();
      if (!niuniuCardPlayers.contains(dealer.getPlayerId())) {
        niuniuCardPlayers.add(dealer.getPlayerId());
      }
    }

    msgMgr.sendDealCardsMsg(dealer);
    LOG.info("[{}]发送庄家[{}][{}]牌[{}]", THIS_GAME.getDesc(), dealer.getPlayerId(),
        dealer.getPlayerName(), dealer.getBestCards());
  }

  /**
   * 给闲家发牌(由于庄家的牌先发，闲家发牌的同时输赢已经出来了，即billChips已经计算出来了) .
   * 
   * @param seat 座位信息.
   * @param cards .
   */
  private void dealPlayerCards(MustNiuNiuSeat seat, List<NiuNiuCard> cards,
      List<MustNiuNiuCardType> cardTypes) {
    MustNiuNiuCardType seatCardsType =
        MustNiuNiuCardsTypeGetter.getCardsType(cards, seat.getBestCards(), cardTypes);
    // 如果不是同一个对象，清空并赋值
    if (!seat.getCards().equals(cards)) {
      seat.getCards().clear();
      seat.getCards().addAll(cards);
    }
    seat.setCardsType(seatCardsType);

    MustNiuNiuSeat dealer = seat.getTable().dealer();
    List<NiuNiuCard> dealerCards = dealer.getCards();
    MustNiuNiuCardType dealerCardsType = dealer.getCardsType();

    HuohuaAssert.isTrue(EmptyUtil.listIsNotEmpty(seat.getCards()));

    boolean win = MustNiuNiuCardsTypeComparator.compare(seat.getCards(), seatCardsType,
        dealerCards, dealerCardsType);
    long betedchips = seat.getBetedchips();

    MustNiuNiuTable table = seat.table();

    if (table.isNiuNiuBeBanker() && seatCardsType.niu >= MustNiuNiuCardType.NIU_NIU.niu) {
      List<Long> niuniuCardPlayers = table.getNiuNiuCardTypePlayers();
      if (!niuniuCardPlayers.contains(seat.getPlayerId())) {
        niuniuCardPlayers.add(seat.getPlayerId());
      }
    }

    // 结算下自己
    int multiple = 0;
    if (win) {
      multiple = table.getCardTypeMap().get(seatCardsType) * dealer.getCallDealerMultiple();
    } else {
      multiple = table.getCardTypeMap().get(dealerCardsType) * dealer.getCallDealerMultiple();
    }
    long winChips = multiple * betedchips;

    if (!win) {
      winChips = 0L - winChips;
    }
    seat.setBillChips(seat.getBillChips() + winChips); // 结算筹码
    seat.setTotalChips(seat.getTotalChips() + winChips); // 总筹码
    dealer.setBillChips(dealer.getBillChips() - winChips);
    dealer.setTotalChips(dealer.getTotalChips() - winChips); // 总筹码

    // 处理推注
    if (win) {
      // 如果玩家非推注下注,下一把可以推注
      if (!seat.getBetType().equals(BetTypeBo.DOUBLE_EXTR_BET)
          && !seat.getBetType().equals(BetTypeBo.EXTR_BET)) {
        long preWinBetSelft = winChips + seat.getBetedchips();
        // 计算最大推注
        // 最低下注选项
        Integer minBetOption = table.findBetOptionPo().findMinBetChip();
        // 最高推注倍数
        MustNiuNiuExtrBetOptionPo extBetOption = table.findExtrBetOptionPo();

        int maxExtrBetChips = extBetOption.getMultiple() * minBetOption;
        if (preWinBetSelft <= maxExtrBetChips) {
          seat.setPreWinBetSelf(preWinBetSelft);
        }
      }
    }

    // 结算买码
    for (MustNiuNiuSeat s : table.getGameSeats(true)) {
      if (s.getState().equals(SeatState.GAMING)) {
        Long betOtherPlayerId = s.getBetOtherPlayerId();
        if (betOtherPlayerId != null && betOtherPlayerId.equals(seat.getPlayerId())) {
          long betChips = s.getBetOtherBetChips();
          long betOtherWinChips = multiple * betChips;
          if (!win) {
            betOtherWinChips = 0L - betOtherWinChips;
          }
          s.setBillChips(s.getBillChips() + betOtherWinChips); // 结算筹码
          s.setTotalChips(s.getTotalChips() + betOtherWinChips); // 总筹码
          s.setBetOtherWinChips(betOtherWinChips);
          dealer.setBillChips(dealer.getBillChips() - betOtherWinChips);
          dealer.setTotalChips(dealer.getTotalChips() - betOtherWinChips); // 总筹码
        }
      }
    }

    msgMgr.sendDealCardsMsg(seat);
    LOG.info("[{}]发送玩家[{}][{}]牌[{}]", THIS_GAME.getDesc(), seat.getPlayerId(),
        seat.getPlayerName(), seat.getBestCards());
  }
  // ===============

}
